#include "Territoire.hpp"

#include "Camp.hpp"

using namespace std;
using namespace sf;

Territoire::Territoire() : nbDes(0), nbDesCourant(5), indiceCamp(-1)
{
    //ctor
}

void Territoire::setNbDe(int nbD)
{
    this->nbDes=nbD;
}

int Territoire::getNbDe() const
{
    return this->nbDes;
}

void Territoire::setNbDesCourant(int nbD)
{
    this->nbDesCourant=nbD;
}

int Territoire::getNbDesCourant() const
{
    return this->nbDesCourant;
}

void Territoire::setIndice(int indice)
{
    this->indice=indice;
}

int Territoire::getIndice() const
{
    return indice;
}

void Territoire::setIndiceCamp(int indiceCamp)
{
    this->indiceCamp=indiceCamp;

    setFillColor(false);
    setOutlineColor(false);
}

int Territoire::getIndiceCamp() const
{
    return indiceCamp;
}

void Territoire::setFillColor(bool b)
{
    int taille(surface.size());
    for (int i(0);i<taille;i++)
    {
        if (b)
        {
            surface[i].setFillColor( sf::Color::Black );
        }
        else
        {
            //std::cout << "---> idCamp = " << indiceCamp << " - id = " << indice << std::endl;
            surface[i].setFillColor( Camp::Couleurs[indiceCamp] );
        }
    }
}

const Color& Territoire::getFillColor() const
{
    return surface[0].getFillColor();
}

void Territoire::setVoisin(int voisin)
{
    this->voisins.push_back(voisin);
}

int Territoire::getVoisin(int indice) const
{
    return this->voisins[indice];
}

vector<int> Territoire::getVoisins() const
{
    return voisins;
}

int Territoire::getNbVoisins() const
{
    return this->voisins.size();
}

void Territoire::setSurface(const Hexagone& h)
{
    this->surface.push_back(h);
}

const Hexagone& Territoire::getSurface(int indice) const
{
    return this->surface[indice];
}

int Territoire::getNbHexagones() const
{
    return this->surface.size();
}

void Territoire::setFrontiere(const sf::ConvexShape& frontiere)
{
    this->frontiere=frontiere;
}

const sf::ConvexShape& Territoire::getFrontiere() const
{
    return this->frontiere;
}

void Territoire::setOutlineColor(bool b)
{
    if (b)
    {
        this->frontiere.setOutlineColor( sf::Color::Red );
    }
    else
    {
        this->frontiere.setOutlineColor( sf::Color::Black );
    }
}

const Color& Territoire::getOutlineColor() const
{
    return this->frontiere.getOutlineColor();
}

void Territoire::setOutline()
{
    frontiere.setFillColor(Color::Transparent);
    frontiere.setOutlineThickness(3);
}

void Territoire::ajouterHexagone(Hexagone &h,vector<Hexagone> &v)
{
    int premierCommun(-1),dernierCommun(-1),pointAjoute;

    int max(frontiere.getPointCount());

    int pointCourant(0);

    while (pointCourant<max)
    {
        int pointCourantAjoute(0);

        while ((pointCourantAjoute<6)&&(frontiere.getPoint(pointCourant)!=h.getPoint(pointCourantAjoute)))
        {
            pointCourantAjoute++;
        }
        if ((pointCourantAjoute<6)&&(frontiere.getPoint(pointCourant)==h.getPoint(pointCourantAjoute)))
        {
            if (premierCommun==-1)
            {
                premierCommun=pointCourant;
                pointAjoute=pointCourantAjoute;
            }
            else if (dernierCommun<pointCourant)
            {
                dernierCommun=pointCourant;
            }
        }
        pointCourant++;
    }

    if (premierCommun==-1)
    {
        v.push_back(h);
    }
    else
    {
        int diff(6+(2*premierCommun)-(2*dernierCommun));

        frontiere.setPointCount(frontiere.getPointCount()+diff);

        for (int i(max-1);i>(dernierCommun-1);i--)
        {
            frontiere.setPoint(i+diff,frontiere.getPoint(i));
        }

        for (int i(premierCommun+1);i<(dernierCommun+diff);i++)
        {
            pointAjoute=(pointAjoute+1)%6;
            frontiere.setPoint(i,h.getPoint(pointAjoute));
        }
    }
}

void Territoire::dessiner(RenderTarget &target) const
{
    int taille(surface.size());
    for (int i(0);i<taille;i++)
    {
        target.draw(surface[i]);
    }
    target.draw(frontiere);
}

void Territoire::ajouterDes(int nbDes)
{
    if(this->nbDesCourant+this->nbDes+nbDes<=8)
    {
        this->nbDes+=nbDes;
    }
    else
    {
        //-le nombre de dés que l'on veut ajouter ferait
        //dépasser le nombre max de dés possible(soit 8)
    }
}

void Territoire::retirerDes(int nbDes)
{
    if(nbDes<this->nbDes)
    {
        this->nbDes-=nbDes;
    }
    else
    {
        //Le nombre de dés à enlever est plus élever que le
        //nombre de dés que l'on a temporairement sur
        //le territoire(soit this->nbDes)
    }
}

void Territoire::deplacement(Territoire* T, int nbDes)
{
    if(this->memeCamp(T))
    {
        if((nbDes<=this->nbDes)&&(T->nbDesCourant+T->nbDes+nbDes<=8))
        {
            this->nbDes-=nbDes;
            T->nbDes+=nbDes;
        }
    }
}

bool Territoire::memeCamp(Territoire* T)
{
    return (this->indiceCamp==T->indiceCamp);
}

bool Territoire::aCote(Territoire* T)
{
    int i=0;
    while(i<voisins.size()&&voisins[i]!=T->indice)
    {
        i++;
    }
    if(i==voisins.size())
    {
        return false;
    }
    else
    {
        return true;
    }
}

bool Territoire::attaquable(Territoire* T)
{
    return ((this->aCote(T))&&(!(this->memeCamp(T))));
}

bool Territoire::existeChemin(int n,Territoire** terri,Territoire* T)
{
    bool dejavu[n];
    for(int j=0;j<n;j++)
    {
        dejavu[j]=false;
    }
    dejavu[this->indice]=true;
    queue<Territoire *> file;
    file.push(this);
    Territoire* terr;
    bool trouve=false;
        while((!trouve)&&(!file.empty()))
            {
                terr=file.front();
                file.pop();
            for(int i(0);i<terr->voisins.size();i++)
                {
                    if(terr->voisins[i]==T->indice)
                        {
                            trouve=true;
                        }
                    else if((!(dejavu[terr->voisins[i]]))&& this->memeCamp(terri[terr->voisins[i]]))
                    {
                      file.push(terri[terr->voisins[i]]);
                      dejavu[terr->voisins[i]]=true;
                    }
                }
            }
        return trouve;
}

bool Territoire::actionPossible()
{
    return nbDesCourant>1;
}


Territoire::~Territoire()
{
    //dtor
}

